# -*- coding: utf-8 -*-
# @Author: Tim Liu
# @Date: 2024-05-26
# @Last Modified by: Tim Liu
# @Last Modified time: 2024-05-26
import logging

# @Description: api endpoints for knowledge base crud

from fastapi import APIRouter, Depends, Security
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload

from utils.response import SuccessResponse

from crewplus.helper.verify import get_api_key
from crewplus.apps.apikey.models.account_api_key import AccountApiKey
from crewplus.apps.rag.utils.vector_db_tool import  generate_collection_name

from core.database import db_getter
from core.dependencies import IdList
from core.exception import CustomException

from utils import status
from . import schemas, cruds, params, models

app = APIRouter()

###########################################################
#    Knowledge Base Endpoints
###########################################################
@app.get("/knowledgebases", summary="Get knowledge base list")
async def get_knowledgebases(p: params.KnowledgeBaseParams = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    model = models.KnowledgeBaseDB
    options = [joinedload(model.create_user)]
    schema = schemas.KnowledgeBaseListOut
    datas, count = await cruds.KnowledgeBaseDal(db).get_datas(
        **p.dict(),
        v_options=options,
        v_schema=schema,
        v_return_count=True
    )
    return SuccessResponse(datas, count=count)

@app.post("/knowledgebase", summary="Create a knowledge base")
async def create_knowledgebase(data: schemas.KnowledgeBase, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    data.create_user_id = apikey.user_id
    # add by g 20250106
    # create a new collection name by coll_id
    # data.coll_id=data.coll_id
    # data.coll_name=data.coll_name
    schema = schemas.KnowledgeBaseSimpleOut
    knowledge=await cruds.KnowledgeBaseDal(db).get_datas(data_id=None,coll_name=data.coll_name,create_user_id=data.create_user_id,v_schema=schema)
    # knowledge=await find_knowledgebase(data.coll_id,apikey,db)
    logging.info(f"knowledge:{knowledge}")
    if knowledge:
        raise CustomException("Collection name already exists", code=status.HTTP_ERROR)
    data.name=generate_collection_name(coll_name=data.coll_name,coll_id=data.coll_id)
    return SuccessResponse(await cruds.KnowledgeBaseDal(db).create_data(data=data))

# add by g 20250106
@app.get("/knowledgebase/find/{coll_name}", summary="Get a knowledgebase id by collection id and name")
async def find_knowledgebase(coll_name: str, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)
    # await cruds.KnowledgeBaseDal(auth.db).get_data()
    # print(f"coll_id:{coll_id}")
    create_user_id = apikey.user_id
    schema = schemas.KnowledgeBaseSimpleOut
    return SuccessResponse(await cruds.KnowledgeBaseDal(db).get_data(data_id=None,coll_name=coll_name,create_user_id=create_user_id, v_schema=schema))

@app.put("/knowledgebase/{data_id}", summary="Update a knowledge base detail")
async def change_knowledgebase(data_id: int, data: schemas.KnowledgeBase, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)    
    
    return SuccessResponse(await cruds.KnowledgeBaseDal(db).put_data(data_id, data))

@app.get("/knowledgebase/{data_id}", summary="Get a knowledgebase by id")
async def get_knowledgebase(data_id: int, apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)   
        
    schema = schemas.KnowledgeBaseSimpleOut
    return SuccessResponse(await cruds.KnowledgeBaseDal(db).get_data(data_id, v_schema=schema))

@app.delete("/knowledgebases", summary="batch delete knowledge bases", description="batch hard delete knowledge bases from db")
async def delete_knowledgebases(ids: IdList = Depends(), apikey: AccountApiKey = Security(get_api_key), db: AsyncSession = Depends(db_getter)):
    #TODO: check permission, account can only delete owned knowledge bases after login
    if apikey is None:
        raise CustomException("apiKey invalid", code=status.HTTP_ERROR)   
    
    await cruds.KnowledgeBaseDal(db).delete_datas(ids=ids.ids, v_soft=False)
    return SuccessResponse("Successfully deleted")


